
use crate::run_plan::{HandResult};
use std::collections::{HashMap, VecDeque};
use crate::data_frame::window::GroupData;
use crate::data_frame::single_data::SingleData;
use crate::data_frame::value::{ElementValue, RealValue, RealValueType};
use linked_hash_map::LinkedHashMap;
use std::sync::Arc;

pub mod json;
pub mod window;
pub mod single_data;
pub mod value;

pub trait DataFrame: Sync+Send{
    fn clone(&self)->Box<dyn DataFrame>;
    fn serialize(&self)->String;
    fn get_key_value(&self, key: &ElementValue) -> HandResult;
    fn set_key_value(&mut self, key: &ElementValue, v: RealValue) -> HandResult;
    fn delete_key(&mut self, key: &ElementValue)-> HandResult;
    fn key_exist(&self, key: &ElementValue)-> HandResult;
    fn convert_value(&mut self, key:&ElementValue, new_type: Option<RealValueType>)-> HandResult;
    fn encode_value(&mut self, key: &ElementValue)-> HandResult;
    fn decode_value(&mut self, key: &ElementValue)-> HandResult;
}

#[derive(Clone)]
pub enum DataInstance{
    BatchData(Vec<SingleData>),
    GroupData(GroupData),
}

unsafe impl std::marker::Sync for DataInstance{}

impl DataInstance{
    pub fn len(&self)->usize{
        match self{
            DataInstance::BatchData(d) => {
                d.len()
            },
            DataInstance::GroupData(d) => {
                d.len()
            },
        }
    }
}

#[derive(Clone,Eq,PartialEq)]
pub struct MetaData{
    /*
        如果有高亮需求，在此记录高亮
    */
    high_light: HashMap<String,Vec<(usize, usize)>>, //offset,length
    /*
        如果调试需要，在此记录event经过的节点名称路径
    */
    event_flow_path: VecDeque<String>,
    /*
        通用的有序记录功能
    */
    pub sorted_record: LinkedHashMap<String,String>,
    /*
        通用的统计记录功能
    */
    pub statistic_record: HashMap<String, usize>,
    /*
        记录当前数据在哪个work_space
    */
    pub work_space: Arc<String>,
    /*
        记录当前数据在哪个work_node
    */
    pub work_node: Arc<String>,
}

impl MetaData{
    pub fn new()->MetaData{
        return MetaData{
            high_light: HashMap::new(),
            event_flow_path: VecDeque::new(),
            sorted_record: LinkedHashMap::new(),
            statistic_record: HashMap::new(),
            work_space: Arc::new(String::new()),
            work_node: Arc::new(String::new()),
        };
    }
    pub fn append_event_flow_path(&mut self, node_name: &str){
        self.event_flow_path.push_back(node_name.to_string());
    }

    pub fn high_light_insert(&mut self, k : String, v :(usize, usize)) ->  Option<Vec<(usize, usize)>> {
        match self.high_light.get(&k) {
            Some(a) => {
                let mut b = a.clone();
                b.push(v);
                self.high_light.insert(k, b)
            },
            None => {
                self.high_light.insert(k, vec![v])
            },
        }
    }

    pub fn high_light_remove(&mut self, k : &str) ->  Option<Vec<(usize, usize)>> {
        return self.high_light.remove(k)
    }

    pub fn high_light_get(&mut self, k : &str) ->  Option<&Vec<(usize, usize)>> {
        return self.high_light.get(k)
    }
}

#[derive(Clone)]
pub enum ChangeRecord{
    DelKey,                              //删除k
    SetKey(RealValue),                      //给k设置值v
}

impl DataInstance{
    //filter 框架代码
    //func 框架代码
    /*
    pub fn get_value(&self, key: &ElementValue)->HandResult{
        if let Some(cache_data) = self.metadata.change_record.get(key){
            match cache_data{
                ChangeRecord::DelKey => {return HandResult::Err(HandResultFail::new(format!("{:?} deleted",key)));},
                ChangeRecord::SetKey(value) => {return HandResult::Ok(HandResultOk::new(value.clone()));},
            }
        }else{
           return self.data.get_value(&key);
        }
    }
    pub fn set_value(&mut self, key: &ElementValue, value: &RealValue)->HandResult{
        self.metadata.change_record.insert(key.clone(), ChangeRecord::SetKey(value.clone()));
        return HandResult::Ok(HandResultOk::new(RealValue::None));
    }
    pub fn del_key(&mut self, key: &ElementValue)->HandResult{
        self.metadata.change_record.insert(key.clone(), ChangeRecord::DelKey);
        return HandResult::Ok(HandResultOk::new(RealValue::None));
    }

     */
}
